home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DDJ0192.ARJ / DISKIO.C < prev    next >
C/C++ Source or Header  |  1991-09-04  |  6KB  |  257 lines

  1. /****************************************************************
  2.  *                                                              *
  3.  * DISKIO.C Whole disk I/O routines for CB386                   *
  4.  * See makefile for compile directives                          *
  5.  * Al Williams -- August 1991                                   *
  6.  *                                                              *
  7.  ****************************************************************/
  8. #include <stdio.h>
  9. #include <malloc.h>
  10. #include <string.h>
  11. #include <dos.h>
  12. #include "cb386.h"
  13. #include "display.h"
  14.  
  15. /* The BIOS read/write routines use a DOS buffer since
  16.    codebuilder does not transparently move data for these
  17.    BIOS interrupts */
  18.  
  19. /* read count number of sectors via the BIOS
  20.    returns 0 for success */
  21. sector_read(int head,int track, int sector, int drive,
  22.             unsigned char *buf,unsigned count)
  23.    {
  24.    int try=NRTRIES;
  25.    union REGS r;
  26. /* if no dos buffer then allocate one large enough for
  27.    one track */
  28.    if (!dosbuf)
  29.      {
  30.      r.h.ah=0x48;
  31.      r.x.bx=bpb.bytespersec*bpb.secpertrack;
  32.      int86(0x21,&r,&r);
  33.      if (r.x.cflag)
  34.        {
  35.        advise("Not enough DOS memory");
  36.        return 1;
  37.        }
  38.      dosbuf=(char *)r.x.ax;
  39.      }
  40.  
  41. /* do operation up to try times */
  42.    while (try--)
  43.      {
  44.      r.h.ah=2;
  45.      r.h.al=count;
  46.      r.h.dh=head;
  47.      r.h.dl=drive;
  48.      r.h.ch=track;
  49.      r.h.cl=sector;
  50.      r.x.bx=(unsigned)dosbuf;
  51.      int86(0x13,&r,&r);
  52. /* if error... */
  53.      if (r.x.cflag)
  54.        {
  55. /* if not last try */
  56.        if (try)
  57.          {
  58. /* reset drive and try again */
  59.          r.x.ax=0;
  60.          r.h.dl=drive;
  61.          int86(0x13,&r,&r);
  62.          }
  63. /* continue on all errors */
  64.        continue;
  65.        }
  66. /* no error -- move data to user's buffer and return success */
  67.      memcpy(buf,dosbuf,bpb.bytespersec*count);
  68.      return 0;
  69.      }
  70. /* if try runs out -- return 1 */
  71.    return 1;
  72.    }
  73.  
  74.  
  75. /* read entire disk */
  76. read_disk(int drive)
  77.   {
  78.   unsigned i,trk=0,head=0;
  79.   unsigned char *diskp;
  80. /* erase existing image, if any */
  81.   if (diskbuf) free(diskbuf);
  82. /* set up buffer info */
  83.   strcpy(bufinfo.title,"<NONE>");
  84.   bufinfo.source[0]=toupper(drive);
  85.   driveno=bufinfo.source[0]-'A';
  86.   bufinfo.source[1]=':';
  87.   bufinfo.source[2]='\0';
  88.   dosbuf_free();
  89. /* turn on wait indicator on screen */
  90.   wait_on();
  91.   /* read BPB from specified drive */
  92.   bpb.bytespersec=512;  /* default */
  93.   bpb.secpertrack=1;
  94.   if (sector_read(head,0,1,driveno,(unsigned char *)&bpb,1))
  95.     {
  96.     advise("Can't read bpb");
  97.     return 0;
  98.     }
  99.   if (dosbuf) dosbuf_free();
  100.   head=0;
  101.   /* determine size of disk */
  102.   bufinfo.size=disksize=
  103.      (sectorct=bpb.nrsectors?bpb.nrsectors:
  104.        bpb.hugesectors)
  105.        *bpb.bytespersec;
  106.   /* allocate space */
  107.   diskbuf=(unsigned char *)malloc(disksize);
  108.   if (!diskbuf)
  109.     {
  110.     advise("Not enough free memory");
  111.     return 0;
  112.     }
  113.   /* read entire disk */
  114.   diskp=diskbuf;
  115.   goxy(0,12);
  116.   histogram(-1,60);
  117.   curshide();
  118.   for (i=0;i<sectorct;i+=bpb.secpertrack)
  119.     {
  120.     histogram(i,sectorct);
  121.     if (sector_read(head,trk,1,driveno,diskp,bpb.secpertrack))
  122.         {
  123.         char errbuf[80];
  124.         sprintf(errbuf,"\aWarning: bad sector at %u:%u\n",head,trk);
  125.         if (advise(errbuf)==-1)
  126.           {
  127.           cleanup();  /* kill incomplete buffer */
  128.           return 0;
  129.           }
  130.         }
  131.     diskp+=bpb.bytespersec*bpb.secpertrack;
  132.     if (++head>=bpb.nrheads)
  133.         {
  134.         head=0;
  135.         trk++;
  136.         }
  137.     }
  138.   bufinfo.dirty=1;
  139.   histogram(i,i);
  140.   bufinfo.csum=checksum();
  141.   wait_off();
  142.   return 1;
  143.   }
  144.  
  145. /* free dos buffer */
  146. dosbuf_free()
  147.   {
  148.   union REGS r;
  149.   if (!dosbuf) return;
  150.   r.h.ah=0x49;
  151.   r.x.dx=(unsigned int)dosbuf;
  152.   int86(0x21,&r,&r);
  153.   if (r.x.cflag)
  154.     advise("Memory allocation error");
  155.   dosbuf=NULL;
  156.   }
  157.  
  158.  
  159. /* write count sectors via BIOS */
  160. sector_write(int head,int track, int sector, int drive,
  161.              unsigned char *buf,unsigned count)
  162.    {
  163.    int try=NRTRIES;
  164.    union REGS r;
  165. /* If no dos buffer, allocate one */
  166.    if (!dosbuf)
  167.      {
  168.      r.h.ah=0x48;
  169.      r.x.bx=bpb.bytespersec*bpb.secpertrack;
  170.      int86(0x21,&r,&r);
  171.      if (r.x.cflag)
  172.        {
  173.        advise("Not enough DOS memory");
  174.        return;
  175.        }
  176.      dosbuf=(char *)r.x.ax;
  177.      }
  178. /* copy data to dosbuffer */
  179.    memcpy(dosbuf,buf,bpb.bytespersec*count);
  180. /* retry up to try times */
  181.    while (try--)
  182.      {
  183.      r.h.ah=3;
  184.      r.h.al=count;
  185.      r.h.dh=head;
  186.      r.h.dl=drive;
  187.      r.h.ch=track;
  188.      r.h.cl=sector;
  189.      r.x.bx=(unsigned)dosbuf;
  190.      int86(0x13,&r,&r);
  191. /* if error.... */
  192.      if (r.x.cflag)
  193.        {
  194. /* if not last try... */
  195.        if (try)
  196.          {
  197. /* reset drive and try again */
  198.          r.x.ax=0;
  199.          r.h.dl=drive;
  200.          int86(0x13,&r,&r);
  201.          }
  202. /* continue for all errors */
  203.        continue;
  204.        }
  205. /* return success */
  206.      return 0;
  207.      }
  208. /* fail */
  209.    return 1;
  210.    }
  211.  
  212. /* write entire disk */
  213. write_disk(int drive)
  214.   {
  215.   int fmt=0;
  216.   unsigned i,trk=0,head=0;
  217.   unsigned char *diskp;
  218.   drive=toupper(drive)-'A';
  219. /* turn on wait indicator */
  220.   wait_on();
  221. retry:
  222.   goxy(0,12);
  223.   histogram(-1,60);
  224.   curshide();
  225.   head=0;
  226.   diskp=diskbuf;
  227. /* write entire disk a track at a time */
  228.   for (i=0;i<sectorct;i+=bpb.secpertrack)
  229.     {
  230.     histogram(i,sectorct);
  231.     if (sector_write(head,trk,1,drive,diskp,bpb.secpertrack))
  232.        {
  233. /* if error and format flag is on then error */
  234.        if (fmt)
  235.          {
  236.          advise("Write error");
  237.          return 0;
  238.          }
  239. /* format disk and set format flag */
  240.        format(drive);
  241.        fmt=1;
  242. /* retry (next error is fatal) */
  243.        goto retry;
  244.        }
  245.     diskp+=bpb.bytespersec*bpb.secpertrack;
  246.     if (++head>=bpb.nrheads)
  247.         {
  248.         head=0;
  249.         trk++;
  250.         }
  251.     }
  252.   histogram(i,i);
  253.   bufinfo.dirty=0;
  254.   wait_off();
  255.   return 1;
  256.   }
  257.